package eteam.aps.service.impl;

import eteam.aps.common.component.LoginUserRedisService;
import eteam.aps.common.constant.NumType;
import eteam.aps.common.constant.ProductType;
import eteam.aps.common.entity.ParentEntity;
import eteam.aps.common.exceptions.BusinessException;
import eteam.aps.common.helper.Assert;
import eteam.aps.common.helper.Helper;
import eteam.aps.mapper.ProductNumberMapper;
import eteam.aps.model.dto.ProductNumberDto;
import eteam.aps.model.dto.ProductNumberSaveDto;
import eteam.aps.model.entity.MocoRders;
import eteam.aps.model.entity.ProductNumber;
import eteam.aps.service.ProductNumberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 产品序号明细;产品序号 业务层实现类
 *
 * @author LiuLei
 */
@Service
public class ProductNumberServiceImpl implements ProductNumberService {

    @Autowired
    private ProductNumberMapper productNumberMapper;

    @Autowired
    private LoginUserRedisService loginUserRedisService;

    @Override
    @Transactional
    public List<ProductNumber> savePn(ProductNumberSaveDto productNumberSaveDto) throws Exception {
        MocoRders mocoRders = productNumberSaveDto.getMocoRders();
        int selC = productNumberMapper.selectCountByMocCode(ParentEntity.FSTATE_DELETED, mocoRders.getfMocCode());
        int ct;
        if (productNumberSaveDto.getCount() == null) {
            Assert.isTrue(mocoRders.getfQty().compareTo(BigDecimal.valueOf(selC)) == 0, "暂无需求数量！");
            ct = mocoRders.getfQty().subtract(BigDecimal.valueOf(selC)).toBigInteger().intValue();
        } else {
            ct = productNumberSaveDto.getCount();
            Assert.isTrue(ct <= 0, "生成数量必须大于0！");
            Assert.isTrue(mocoRders.getfQty().compareTo(BigDecimal.valueOf(ct + selC)) < 0, "生成数不能大于需求数！");
        }
        List<ProductNumber> list = new LinkedList<>();
        int location = productNumberSaveDto.getLocation();
        String fuserid = loginUserRedisService.getUser().getFuserid();
        String startNo = productNumberSaveDto.getStartNo();
        Map<String, String> sbcSeqMap = new HashMap();
        for (int i = 0; i < ct; i++) {
            int no = Integer.parseInt(startNo) + i;
            String seqNo = Helper.fillNum(no, Math.max(String.valueOf(no).length(), startNo.length()));
            String sbc;
            if (location == NumType.PREFIX)
                sbc = seqNo + productNumberSaveDto.getfFront() + productNumberSaveDto.getfLastStr();
            else if (location == NumType.CENTER)
                sbc = productNumberSaveDto.getfFront() + seqNo + productNumberSaveDto.getfLastStr();
            else sbc = productNumberSaveDto.getfFront() + productNumberSaveDto.getfLastStr() + seqNo;
            sbcSeqMap.put(seqNo, sbc);
        }
        if (!sbcSeqMap.isEmpty()) {
            int count = productNumberMapper.selectCountByBarCode(sbcSeqMap.values());
            Assert.isTrue(count > 0, "已存在相同条码的产品，不能重复生成！");
            sbcSeqMap.forEach((seqNo, sbc) -> {
                ProductNumber productNumber = new ProductNumber(mocoRders.getfMoId(), // 工单Id
                        mocoRders.getfMocCode(), // 工单代号
                        mocoRders.getfMoDId(),// 工单编号
                        mocoRders.getfInvCode(), // 品号
                        sbc, //条码
                        productNumberSaveDto.getfFront(), // 前缀
                        productNumberSaveDto.getfLastStr(), // 后缀
                        seqNo // 序列号
                );
                Helper.setDefaultAddValue(productNumber, fuserid);
                list.add(productNumber);
            });
            if (!list.isEmpty()) productNumberMapper.savePn(list);
        }
        return list;
    }

    @Override
    @Transactional
    public int batchDel(List<String> list) {
        int del = productNumberMapper.batchDel(ProductType.DRAFT, list);
        if (del != list.size()) throw new BusinessException("有不为草稿状态的条码，不能删除！");
        return del;
    }

    @Override
    @Transactional
    public int updateProductNumber(String fId, String bar) throws Exception {
        int one = productNumberMapper.selPnOneByBarCode(bar, ParentEntity.FSTATE_DELETED);
        if (one > 0) {
            throw new BusinessException(HttpStatus.BAD_REQUEST, "已存在该条码号！");
        }
        Map<String, Object> map = new HashMap<>(4);
        map.put("fId", fId);
        map.put("bar", bar);
        map.put("modify", loginUserRedisService.getUser().getFuserid());
        map.put("time", LocalDateTime.now());
        map.put("draft", ProductType.DRAFT);
        return productNumberMapper.updateProductNumber(map);
    }

    @Override
    public String getMaxSeqNo(ProductNumberDto productNumberDto) {
        String bar = "";
        switch (productNumberDto.getLocation()) {
            case -1:
                bar = '%' + productNumberDto.getfFront() + productNumberDto.getfLastStr();
                break;
            case 0:
                bar = productNumberDto.getfFront() + '%' + productNumberDto.getfLastStr();
                break;
            case 1:
                bar = productNumberDto.getfFront() + productNumberDto.getfLastStr() + '%';
                break;
            default:
                throw new BusinessException("序号存放位置不合法，只能是【-1 首位，0 中间，1 最后】");
        }
        Map<String, Object> map = new HashMap<>(2);
        map.put("type", ParentEntity.FSTATE_DELETED);
        map.put("bar", bar);
        return productNumberMapper.getMaxSeqNo(map);
    }
}
